#include "led_func.h"

LED_FUNC_ST led_func_st[3];
void register_led_interface(uint8_t index, uint8_t mode, led_ON_OFF_FUN led_on, led_ON_OFF_FUN led_off)
{
    led_func_st[index].mode = mode;
    led_func_st[index].led_on = led_on;
    led_func_st[index].led_off = led_off;
}
void led_blink_cycle(void)
{
    uint8_t i;
    for (i = 0; i < 3; i++)
    {
        led_blink_excute(&led_func_st[i]);
    }
}
uint8_t get_current_status_need_remain_tickets(uint8_t mode, uint8_t status)
{
    switch (mode)
    {
    case LED_OFF:
    {
        switch (status)
        {
        case 0:
            return 0;
        case 1:
            return 20;
        case 2:
            return 0;
        case 3:
            return 20;
        default:
            return 0xFF;
        }
    }
    case LED_ON:
    {
        switch (status)
        {
        case 0:
            return 20;
        case 1:
            return 0;
        case 2:
            return 20;
        case 3:
            return 0;
        default:
            return 0xFF;
        }
    }
    case FLASH_LONG_AVERAGE: // ON20 OFF20
    {
        return 20;
    }
    case FLASH_SHORT_AVERAGE: // ON5 OFF5
    {
        return 5;
    }

    case FLASH_FAST: // ON20 OFF5
    {
        return 2;
    }
    case FLASH_LONG_SHORT: // ON20 OFF20 ON5 off 5
    {
        switch (status)
        {
        case 0:
            return 20;
        case 1:
            return 5;
        case 2:
            return 20;
        case 3:
            return 5;
        default:
            return 0xFF;
        }
    }

    case FLASH_SHORT_LONG: // ON20 OFF20 ON5 off 5
    {
        switch (status)
        {
        case 0:
            return 5;
        case 1:
            return 20;
        case 2:
            return 5;
        case 3:
            return 20;
        default:
            return 0xFF;
        }
    }
    case FLASH_SHORT_SHORT_LONG_LONG: // ON5 OFF5 ON 20 OFF 20
    {
        switch (status)
        {
        case 0:
            return 5;
        case 1:
            return 5;
        case 2:
            return 20;
        case 3:
            return 20;
        default:
            return 0xFF;
        }
    }
    case FLASH_LONG_LONG_LONG_SHORT: // ON20 OFF20 ON 20 OFF5
    {
        switch (status)
        {
        case 0:
            return 20;
        case 1:
            return 20;
        case 2:
            return 20;
        case 3:
            return 5;
        default:
            return 0xFF;
        }
    }
    case FLASH_SHORT_SHORT_SHORT_LONG: // ON5 OFF5 ON 5 OFF20
    {
        switch (status)
        {
        case 0:
            return 5;
        case 1:
            return 5;
        case 2:
            return 5;
        case 3:
            return 20;
        default:
            return 0xFF;
        }
    }
    default:
        return 0;
    }
}
uint8_t led_output_and_status_change(LED_FUNC_ST *led_fs)
{
    led_fs->current_tickets++;
    if (led_fs->current_tickets >= led_fs->remain_tickets)
    {
        led_fs->status++;
        if (led_fs->status > 3)
        {
            led_fs->status = 0;
        }
        led_fs->remain_tickets = get_current_status_need_remain_tickets(led_fs->mode, led_fs->status);
        led_fs->current_tickets = 0;
        return 0;
    }
    return 1;
}
void led_blink_excute(LED_FUNC_ST *led_fs)
{
    switch (led_fs->status)
    {
    case 0: //
        if (led_output_and_status_change(led_fs))
        {
            if (led_fs->led_on != 0)
            {
                led_fs->led_on();
            }
        }
        /* code */
        break;
    case 1:
        if (led_output_and_status_change(led_fs))
        {
            if (led_fs->led_off != 0)
            {
                led_fs->led_off();
            }
        }
        break;
    case 2:
        if (led_output_and_status_change(led_fs))
        {
            if (led_fs->led_on != 0)
            {
                led_fs->led_on();
            }
        }
        break;
    case 3:
        if (led_output_and_status_change(led_fs))
        {
            if (led_fs->led_off != 0)
            {
                led_fs->led_off();
            }
        }
        break;
    default:
        break;
    }
}

void set_led_blink_mode(uint8_t index, uint8_t mode)
{
    if (index < 3)
    {
        led_func_st[index].mode = mode;
    }
}
